<?php

namespace App\Kuafu\Export\Service\ExportFactory;

use App\Kuafu\Activity\Model\ActivityImageMappingModel;
use App\Kuafu\Config\Service\ConfigService;
use App\Kuafu\Shop\Model\SourceMaterialTemplateModel;
use App\Kuafu\Shop\Service\ToolsService;
use App\Remote\Tiger\Common\CommonRemote;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Kuafu\File\FileUtil;

/**
 * app-创建物料素材模版-压缩包
 */
class CreateSourceMaterialCompressService extends BaseExportService
{
    private string $localPath  = '';
    private string $tmpDir     = '';
    private int    $activityId = 0;
    private string $tempPath   = '';

    public function __destruct()
    {
        // 清理临时文件
        $fileSystem = getFileSystem();
        if ($this->tmpDir) {
            if ($fileSystem->isDirectory($this->tmpDir)) {
                $fileSystem->deleteDirectory($this->tmpDir);
            }
        }
        if ($this->tempPath) {
            if ($fileSystem->isDirectory($this->tempPath)) {
                $fileSystem->deleteDirectory($this->tempPath);
            }
        }
        if ($this->localPath) {
            if ($fileSystem->isDirectory($this->localPath)) {
                $fileSystem->deleteDirectory($this->localPath);
            }
        }
    }

    public function query(): self
    {
        $this->activityId = (int)($this->params['activityId'] ?? 0);
        $rmsUserId        = (int)($this->params['rmsUserId'] ?? 0);
        $shopId           = (int)($this->params['shopId'] ?? 0);
        $data             = (array)($this->params['data'] ?? []);
        $ids              = (array)($this->params['ids'] ?? []);

        $this->tmpDir = sys_get_temp_dir() . '/rms_api/activity/materials/' . Str::random(8);
        if (is_dir($this->tmpDir)) {
            // 清空这个dir
            getFileSystem()->deleteDirectory($this->tmpDir, true);
            @rmdir($this->tmpDir);
        }
        mkdir($this->tmpDir, 0777, true);
        $this->localPath = dirname($this->tmpDir) . '/materials_' . Str::random(8) . '.7z';

        // 单个模版需要匹配门店信息
        $tempData = ConfigService::getConfigDetail('tools', 'activityMaterialsOneConfig')['value'] ?? [];
        $tempData = collect($tempData)->keyBy('id')->toArray();

        foreach ($ids as $id) {
            if ($tempData && isset($tempData[$id]) && $tempData[$id]) {
                foreach ($tempData[$id] as $k => $temp) {
                    if (strpos($k, 'input') !== false) {
                        if ($k == 'input1') {
                            $temp = sprintf($temp, $data['shopName']);
                        }
                        if ($k == 'input4') {
                            $temp = sprintf($temp, $data['address']);
                        }
                        $data[$k] = $temp;
                    }
                }
            }
            /*if ($id == (config('app.env') == 'qa' ? 137 : 143)) {
                $data['input1'] = "①本券仅限夸父炸串{$data['shopName']}使用;";// 门店名称
                $data['input2'] = '②此券每人限领1张,仅限本人凭券到店堂食核销,不可代领;';// 2
                $data['input3'] = '③此券不兑换、不找零,不与其他优惠同享.';// 3
                $data['input4'] = "地址：{$data['address']}";// 门店地址
            }*/
            $info = SourceMaterialTemplateModel::query()
                                               ->withoutGlobalScope('isDel')
                                               ->where('id', $id)
                                               ->first();//模版信息
            if (!$info) {
                continue;
            }

            // 生成文件
            $res = (new ToolsService())->generateTemplateImg($info, $data, $rmsUserId, $shopId);

            $this->tempPath = $res['templateBasePath'] ?? '';//返回文件存储临时目录

            Log::info('CreateSourceMaterial_res', ['res' => $res, 'id' => $id]);

            // 同一个文件夹
            self::streamDownload($this->tmpDir . '/' . $info['name'] . '.png', $res['upright']);
            if ($res['reverse']) {
                self::streamDownload($this->tmpDir . '/' . $info['name'] . '_背面.png', $res['reverse']);
            }
        }

        // 私域活动物料-其他需要下载的文件
        $otherDownload = ConfigService::getConfigDetail('tools', 'activityMaterialOtherDownload')['value'] ?? [];
        if ($otherDownload) {
            foreach ($otherDownload as $v) {
                $tempPath = $this->tmpDir;
                if ($v['folderName']) {
                    $tempPath = $this->tmpDir . '/' . $v['folderName'];
                    if (!is_dir($tempPath)) {
                        mkdir($tempPath, 0777, true);
                    }
                }
                self::streamDownload($tempPath . '/' . $v['name'], $v['url']);
            }
        }
        self::makeArchive();// 执行压缩命令

        return $this;
    }

    public function path(): string
    {
        $res = $this->upload($this->localPath);

        // 生成短链
        $oldUrl       = FileUtil::domain() . '/' . $res;
        $shortLinkUrl = CommonRemote::generateShortLinkUrl($oldUrl)['shortUrl'] ?? '';

        // 更新私域活动物料素材压缩包地址
        ActivityImageMappingModel::query()->updateOrCreate([
            'activityId' => $this->activityId,
            'type'       => ActivityImageMappingModel::TYPE_MATERIAL_COMPRESS,
        ], [
            'imageUrl' => $shortLinkUrl
        ]);
        Log::info('createSourceMaterial-生成短链', [
            'oldUrl'       => $oldUrl,
            'shortLinkUrl' => $shortLinkUrl,
            'params'       => $this->params,
        ]);

        return $res;
    }


    public function streamDownload(string $localPath, string $url)
    {
        $fd = $local = null;
        @unlink($localPath);
        try {
            $basepath = base_path($localPath);
            if (!is_dir($basepath)) {
                mkdir($basepath, 0777, true);
            }
            $local = fopen($localPath, 'wb');
            $fd    = fopen($url, 'rb');
            while (!feof($fd)) {
                fwrite($local, fread($fd, 1024 * 1024), 1024 * 1024);
            }
        } catch (\Exception $e) {
            Log::info('streamDownloadErr:', [
                'localPath' => $localPath,
                'url'       => $url,
                'msg'       => $e->getMessage(),
            ]);
        }
        is_resource($fd) && fclose($fd);
        is_resource($local) && fclose($local);
    }

    public function makeArchive()
    {
        // 删掉空文件
        foreach (app(Filesystem::class)->files($this->tmpDir) as $v) {
            if ($v->getSize() < 1) {
                @unlink($v->getPathname());
            }
        }
        putenv('LC_ALL=en_US.UTF-8');
        $command = sprintf('7za a -mx0 -mmt2 "%s" "%s"', $this->localPath, rtrim($this->tmpDir, '/') . '/*');
        $r       = shell_exec($command);
        if (null === $r) {
            $r = 'null';
        }
        if (false === $r) {
            $r = 'false';
        }
        Log::info("私域活动物料素材文件下载：，临时目录：{$this->tmpDir}，执行命令：[{$command}]，执行结果：" . $r);
    }
}
